package com.gitee.feizns.quickstart.ding.talk.api.top.api;

import com.dingtalk.api.request.OapiRoleListRequest;
import com.dingtalk.api.request.OapiUserListsimpleRequest;
import com.dingtalk.api.request.OapiV2DepartmentCreateRequest;
import com.dingtalk.api.request.OapiV2DepartmentUpdateRequest;
import com.dingtalk.api.request.OapiV2UserCreateRequest;
import com.dingtalk.api.request.OapiV2UserListRequest;
import com.dingtalk.api.request.OapiV2UserUpdateRequest;
import com.dingtalk.api.response.OapiRoleGetroleResponse;
import com.dingtalk.api.response.OapiRoleGetrolegroupResponse;
import com.dingtalk.api.response.OapiRoleListResponse;
import com.dingtalk.api.response.OapiUserListsimpleResponse;
import com.dingtalk.api.response.OapiV2DepartmentCreateResponse;
import com.dingtalk.api.response.OapiV2DepartmentGetResponse;
import com.dingtalk.api.response.OapiV2DepartmentListparentbyuserResponse;
import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
import com.dingtalk.api.response.OapiV2UserCreateResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.dingtalk.api.response.OapiV2UserListResponse;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.role.AddRole;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.role.AddRoleGroup;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.role.AddRolesForEmps;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.role.DeleteRole;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.role.GetRole;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.role.GetRoleGroup;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.role.RemoveRolesForEmps;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.role.RoleList;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.role.UpdateRole;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.user.ListId;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.user.ListSimple;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.department.ListParentByDept;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.department.ListParentByUser;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.department.ListSub;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.department.ListSubId;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.user.Create;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.user.Delete;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.user.Get;
import com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.user.Update;
import com.gitee.feizns.quickstart.ding.talk.api.v10.oauth2.AccessToken;
import com.gitee.feizns.quickstart.ding.talk.utils.Utils;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * 通讯录接口
 * @author feizns
 * @since 2025/3/26
 */
@Getter
@RequiredArgsConstructor
public class ContactsApi {

    /**
     * 访问令牌
     */
    private final AccessToken accessToken;

    /**
     * 创建用户（必填：用户名、手机号、部门编号列表）
     * @param req 要求
     * @return {@link OapiV2UserCreateResponse.UserCreateResponse }
     */
    public OapiV2UserCreateResponse.UserCreateResponse createUser(OapiV2UserCreateRequest req) {
        return Create.execute(accessToken.get(), req);
    }

    /**
     * 修改用户
     * @param req {@link OapiV2UserUpdateRequest}
     * @return {@link OapiV2UserCreateResponse.UserCreateResponse }
     */
    public String updateUser(OapiV2UserUpdateRequest req) {
        return Update.execute(accessToken.get(), req);
    }

    /**
     * 删除用户
     * @param userid 用户 ID
     * @return {@link OapiV2UserCreateResponse.UserCreateResponse }
     */
    public String deleteUser(String userid) {
        return Delete.execute(accessToken.get(), userid);
    }

    /**
     * 获取用户
     * @param userid 用户 ID
     * @return {@link String }
     */
    public OapiV2UserGetResponse.UserGetResponse getUser(String userid) {
        return Get.execute(accessToken.get(), userid);
    }

    /**
     * 获取简单用户列表根据部门编号
     * @param req 要求
     * @return {@link String }
     */
    public OapiUserListsimpleResponse.PageResult getSimpleUserListByDeptId(OapiUserListsimpleRequest req) {
        return ListSimple.execute(accessToken.get(), req);
    }

    /**
     * 获取简单用户列表根据部门编号
     * @param deptId 部门编号
     * @return {@link String }
     */
    public List<OapiUserListsimpleResponse.ListUserSimpleResponse> getSimpleUserListByDeptId(Long deptId) {
        return ListSimple.execute(accessToken.get(), deptId);
    }

    /**
     * 获取用户ID列表根据部门编号
     * @param deptId 部门编号
     * @return {@link String }
     */
    public List<String> getUseridListByDeptId(Long deptId) {
        return ListId.execute(accessToken.get(), deptId);
    }

    /**
     * 获取部门下的所有用户信息
     * @param req 要求
     * @return {@link String }
     */
    public OapiV2UserListResponse.PageResult getUserListByDeptId(OapiV2UserListRequest req) {
        return com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.user.List.execute(accessToken.get(), req);
    }

    /**
     * 获取部门下的所有用户信息
     * @param deptId 部门编号
     * @return {@link String }
     */
    public List<OapiV2UserListResponse.ListUserResponse> getUserListByDeptId(Long deptId) {
        return com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.user.List.execute(accessToken.get(), deptId);
    }

    /**
     * 创建部门
     * @param req 要求
     * @return {@link Object }
     */
    public OapiV2DepartmentCreateResponse.DeptCreateResponse createDept(OapiV2DepartmentCreateRequest req) {
        return com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.department.Create.execute(accessToken.get(), req);
    }

    /**
     * 修改部门
     * @param req 要求
     * @return {@link String }
     */
    public String updateDept(OapiV2DepartmentUpdateRequest req) {
        return com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.department.Update.execute(accessToken.get(), req);
    }

    /**
     * 删除部门
     * @param deptId 部门编号
     * @return {@link String }
     */
    public String deleteDept(Long deptId) {
        return com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.department.Delete.execute(accessToken.get(), deptId);
    }

    /**
     * 遍历所有部门
     * @param deptConsumer 部门消费者
     */
    public void eachDept(Consumer<OapiV2DepartmentGetResponse.DeptGetResponse> deptConsumer) {
        //根部门编号=1
        eachDept(1L, deptConsumer);
    }

    /**
     * 遍历指定部门及其所有子部门
     * @param deptId 部门编号
     * @param deptConsumer 部门消费者
     */
    public void eachDept(Long deptId, Consumer<OapiV2DepartmentGetResponse.DeptGetResponse> deptConsumer) {
        OapiV2DepartmentGetResponse.DeptGetResponse dept = getDept(deptId);
        deptConsumer.accept(dept);
        getSubDeptIdList(dept.getDeptId()).forEach(subDeptId -> eachDept(subDeptId, deptConsumer));
    }

    /**
     * 查询部门详情
     * @param deptId 部门编号
     * @return {@link String }
     */
    public OapiV2DepartmentGetResponse.DeptGetResponse getDept(Long deptId) {
        return com.gitee.feizns.quickstart.ding.talk.api.top.api.v2.department.Get.execute(accessToken.get(), deptId);
    }

    /**
     * 获取子部门列表
     * @param deptId 部门编号
     * @return {@link List }<{@link OapiV2DepartmentListsubResponse.DeptBaseResponse}>
     */
    public List<OapiV2DepartmentListsubResponse.DeptBaseResponse> getSubDeptList(Long deptId) {
        return ListSub.execute(accessToken.get(), deptId);
    }

    /**
     * 获取子部门编号列表
     * @param deptId 部门编号
     * @return {@link List }<{@link Long}>
     */
    public List<Long> getSubDeptIdList(Long deptId) {
        return ListSubId.execute(accessToken.get(), deptId);
    }

    /**
     * 获取指定部门的所有父部门列表
     * @param deptId 部门编号
     * @return {@link List }<{@link Long}>
     */
    public List<Long> getListParentByDept(Long deptId) {
        return ListParentByDept.execute(accessToken.get(), deptId);
    }

    /**
     * 获取指定用户的所有父部门列表
     * @param userid 用户 ID
     * @return {@link List }<{@link Long}>
     */
    public List<OapiV2DepartmentListparentbyuserResponse.DeptParentResponse> getListParentByUser(String userid) {
        return ListParentByUser.execute(accessToken.get(), userid);
    }

    /**
     * 创建角色（支持角色和角色组）
     * @param roleName 角色名称
     * @param groupId 群编号
     * @return {@link Long } 角色编号
     */
    public Long createRole(String roleName, Long groupId) {
        return Utils.isRoleGroup(groupId) ? createRoleGroup(roleName) : AddRole.execute(accessToken.get(), roleName, groupId);
    }

    /**
     * 创建角色组
     * @param roleGroupName 角色组名称
     * @return {@link Long } 角色组编号
     */
    public Long createRoleGroup(String roleGroupName) {
        return AddRoleGroup.execute(accessToken.get(), roleGroupName);
    }

    /**
     * 修改角色名称（支持角色和角色组）
     * @param roleId 角色编号
     * @param roleName 角色名称
     * @return {@link Long } 角色组编号
     */
    public String updateRole(Long roleId, String roleName) {
        return UpdateRole.execute(accessToken.get(), roleId, roleName);
    }

    /**
     * 删除角色（支持同时删除角色和角色组）
     * @param roleId 角色编号
     * @return {@link Long } 角色组编号
     */
    public String deleteRole(Long roleId) {
        return DeleteRole.execute(accessToken.get(), roleId);
    }

    /**
     * 获取角色详情
     * @param roleId 角色编号
     * @return {@link Long } 角色组编号
     */
    public OapiRoleGetroleResponse.OpenRole getRole(Long roleId) {
        return GetRole.execute(accessToken.get(), roleId);
    }

    /**
     * 获取角色列表
     * @param req 要求
     * @return {@link Long } 角色组编号
     */
    public OapiRoleListResponse.PageVo getRoleList(OapiRoleListRequest req) {
        return RoleList.execute(accessToken.get(), req);
    }

    /**
     * 获取角色列表
     * @return {@link List }<{@link OapiRoleListResponse.OpenRoleGroup }>
     */
    public List<OapiRoleListResponse.OpenRoleGroup> getRoleList() {
        List<OapiRoleListResponse.OpenRoleGroup> result = new ArrayList<>();
        long offset = 0L;
        Long size = 200L;
        OapiRoleListResponse.PageVo vo;
        do {
            OapiRoleListRequest req = new OapiRoleListRequest();
            req.setOffset(offset++);
            req.setSize(size);
            vo = RoleList.execute(accessToken.get(), req);
            result.addAll(vo.getList());
        } while ( vo.getHasMore() );
        return result;
    }

    /**
     * 获取角色组
     * @param groupId 群编号
     * @return {@link Object }
     */
    public OapiRoleGetrolegroupResponse.OpenRoleGroup getRoleGroup(Long groupId) {
        return GetRoleGroup.execute(accessToken.get(), groupId);
    }

    /**
     * 为用户添加角色
     * @param roleIds 角色编号列表
     * @param userIds 用户编号列表
     * @return {@link String }
     */
    public String addRolesForUsers(List<String> userIds, List<Long> roleIds) {
        return AddRolesForEmps.execute(accessToken.get(), String.join(",", userIds), roleIds.stream().map(Objects::toString).collect(Collectors.joining(",")));
    }

    /**
     * 为用户删除角色
     * @param roleIds 角色编号列表
     * @param userIds 用户编号列表
     * @return {@link String }
     */
    public String removeRolesForUsers(List<String> userIds, List<Long> roleIds) {
        return RemoveRolesForEmps.execute(accessToken.get(), String.join(",", userIds), roleIds.stream().map(Objects::toString).collect(Collectors.joining(",")));
    }

}
